/** file Convolution.cpp
    author belot.nicolas

*/

#include "Convolution.h"
#include <iostream>
#define max(a,b) (a)>(b)?(a):(b)

namespace libtrckr {
Convolution::Convolution():convolutionS(0){
	convolutionD =  0;
}

Convolution::Convolution(int size):convolutionS(size){
	convolutionD = (double*) malloc(sizeof(double)*size);
	memset(convolutionD,0, sizeof(double)*size);
}

Convolution::Convolution(double* data, int size):convolutionS(size){
	convolutionD = (double*) malloc(sizeof(double)*size);
	memcpy(convolutionD, data,sizeof(double)*size);
}

Convolution::Convolution(const Buffer& b):convolutionS(b.size()){
	convolutionD = (double*) malloc(sizeof(double)*convolutionS);
	memcpy(convolutionD, b.getContent(),sizeof(double)*convolutionS);
}

Convolution::Convolution(const Convolution& f):convolutionS(f.convolutionS){
	convolutionD = (double*) malloc(sizeof(double)*convolutionS);
	memcpy(convolutionD, f.convolutionD,sizeof(double)*convolutionS);

}

Convolution::~Convolution(){
	if(convolutionD!=0)
		free(convolutionD);
}

void Convolution::setContent(double* data, int size){
if(convolutionD==0){
	convolutionD=(double*)malloc(sizeof(double)*size);
}else if(size!=convolutionS){
	if(convolutionD!=0)
		free(convolutionD);
	convolutionD=(double*)malloc(sizeof(double)*size);
}
memcpy(convolutionD,data, sizeof(double)*size);
convolutionS=size;
}

double* Convolution::getCoef() const{
	return convolutionD;
}
uint  Convolution::getSize() const{
	return convolutionS;
}


Convolution Convolution::operator*(const Convolution& c){
	Convolution ret(c);
	ret*=(*this);
	return ret;
}


void Convolution::operator*=(const Convolution& c){
	uint nsize=convolutionS+c.convolutionS;
	double *data=(double*)malloc(sizeof(double)*nsize);
	memset(data,0, sizeof(double)*nsize);
	//for(uint i=0;i<nsize;i++)	
	//	data[i]=.0;

	for(uint i=0;i<convolutionS;i++){
		for(uint j=0;j<c.convolutionS;j++){
			data[i+j]+=convolutionD[i]*c.convolutionD[j];
		}
	}

	free(convolutionD);
	convolutionD=data;
	convolutionS=nsize;
}


Convolution Convolution::operator+(const Convolution& c){
	Convolution ret(c);
	ret+=(*this);
	return ret;
}

void Convolution::operator+=(const Convolution& c){
	if(convolutionS > c.convolutionS){
		for(uint i=0;i<c.convolutionS;i++){
			convolutionD[i]+=c.convolutionD[i];
		}
	}else{
		double *tmp=(double*)malloc(sizeof(double)*c.convolutionS);
		memcpy(tmp,c.convolutionD,c.convolutionS);
		for(uint i=0;i<convolutionS;i++){
			tmp[i]+=convolutionD[i];

		}
		free(convolutionD);
		convolutionD=tmp;
		convolutionS=c.convolutionS;
	}
}


}


